package com.security.sdk.filter;

import com.alibaba.fastjson.JSONObject;
import com.security.sdk.config.JWTConfig;
import com.security.sdk.entity.TokenEntity;
import com.security.sdk.entity.UserEntity;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.ExpiredJwtException;
import io.jsonwebtoken.Jwts;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.web.authentication.www.BasicAuthenticationFilter;

import javax.annotation.Resource;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.*;

@Slf4j
public class JWTAuthenticationTokenFilter extends BasicAuthenticationFilter {

    @Resource
    private JWTConfig jwtConfig;

    public JWTAuthenticationTokenFilter(AuthenticationManager authenticationManager) {
        super(authenticationManager);
    }

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws IOException, ServletException {
        // 获取请求头中JWT的Token
        String tokenHeader = request.getHeader(jwtConfig.getTokenHeader());

        if (null != tokenHeader && tokenHeader.startsWith(jwtConfig.getTokenPrefix())) {
            try {

                // 截取JWT前缀
                String token = tokenHeader.replace(jwtConfig.getTokenPrefix(), "");

                // 解析JWT
                Claims claims = Jwts.parser().setSigningKey(jwtConfig.getSecret()).parseClaimsJws(token).getBody();

                // 获取用户信息
                String username = claims.getSubject();
                String userId=claims.getId();

                if(!StringUtils.isEmpty(username)&&!StringUtils.isEmpty(userId)) {
                    // 获取角色
                    Set<GrantedAuthority> authorities = new HashSet<>();

                    String authority = claims.get("authorities").toString();

                    if(!StringUtils.isEmpty(authority)){
                        Set<String> authorityMap = JSONObject.parseObject(authority, Set.class);
                        for(String auth : authorityMap){
                            if(Objects.nonNull(auth)) {
                                authorities.add(new SimpleGrantedAuthority(auth));
                            }
                        }
                    }
                    //组装参数
                    UserEntity userEntity = new UserEntity();
                    userEntity.setUserName(claims.getSubject());
                    userEntity.setUserId(Long.parseLong(claims.getId()));
                    userEntity.setAuthorities(authorities);
                    UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(userEntity, userId, authorities);
                    SecurityContextHolder.getContext().setAuthentication(authentication);
                }
            } catch (ExpiredJwtException e){
                log.info("Token过期");
            } catch (Exception e) {
                log.info("Token无效");
            }
        }
        chain.doFilter(request, response);
        return;
    }
}
